package com.youku.monitor;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.apache.commons.jcs.access.CacheAccess;
import org.apache.commons.jcs.engine.behavior.ICacheElement;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.youku.model.LogModel;
import com.youku.util.Consts;
import com.youku.util.JCSClient;

public class LogListener implements FileAlterationListener {

	private static final Logger logger = LoggerFactory.getLogger(LogListener.class);

	private String action;

	public LogListener(String action) {
		super();
		this.action = action;
	}

	@Override
	public void onStart(FileAlterationObserver fileAlterationObserver) {
	}

	@Override
	public void onStop(FileAlterationObserver fileAlterationObserver) {
	}

	@Override
	public void onDirectoryCreate(File file) {
		logger.info("创建文件夹" + file.getName());
	}

	@Override
	public void onDirectoryChange(File file) {
		logger.info("改变文件夹" + file.getName());
	}

	@Override
	public void onDirectoryDelete(File file) {
		logger.info("删除文件夹" + file.getName());
	}

	@Override
	public void onFileCreate(File file) {
		readFileToMap(file);
		logger.info("创建文件" + file.getName());
	}

	@Override
	public void onFileChange(File file) {
		readFileToMap(file);
		logger.info("改变文件" + file.getName());
	}

	@Override
	public void onFileDelete(File file) {
		logger.info("删除文件" + file.getName());
	}

	private void readFileToMap(File file) {
		try (Reader reader = new FileReader(file)) {
			List<String> dataList = IOUtils.readLines(reader);
			for (String line : dataList) {
				if (StringUtils.isNotBlank(line)) {
					String[] arr = line.split(Consts.SEPARATOR);
					LogModel model = LogModel.create(action, arr);
					JCSClient.set(action, model.getName(), model);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		combineDupData();
	}

	private void combineDupData() {
		CacheAccess<String, List<LogModel>> cacheAccess = JCSClient.getJCSInstance(action);
		Map<String, List<LogModel>> map = new HashMap<>();
		for (Entry<String, ICacheElement<String, List<LogModel>>> cacheElementEntry : cacheAccess
				.getCacheElements(cacheAccess.getCacheControl().getKeySet()).entrySet()) {
			ICacheElement<String, List<LogModel>> cacheElement = cacheElementEntry.getValue();

			List<LogModel> newCacheVal = elimateDup(cacheElement.getVal());
			map.put(cacheElement.getKey(), newCacheVal);
		}

		cacheAccess.clear();

		for (Entry<String, List<LogModel>> entry : map.entrySet()) {
			cacheAccess.put(entry.getKey(), entry.getValue());
		}
	}

	private List<LogModel> elimateDup(List<LogModel> modelList) {
		Map<String, LogModel> map = new LinkedHashMap<>();
		for (LogModel model : modelList) {
			map.put(model.get(Consts.ELIMATE_DUP_KEY), model);
		}
		return new ArrayList<LogModel>(map.values());
	}

}
